package chapter1;
import java.lang.reflect.Array;

/**
 * exercise 1_3_39
 * @author i062843
 *
 * @param <Item>
 */
public class RingBuffer<Item> {

	public static void main(String[] args) {
		RingBuffer<Integer> rb = new RingBuffer<Integer>(Integer.class, 7);
		System.out.println(rb.isEmpty());
		System.out.println(rb.isFull());
		
		for(int i = 0; i< 10; i++)
		{
			try
			{
				rb.enqueue(i);
				System.out.println("equeue : " + i);
			}
			catch(Exception e)
			{
				System.out.println("enqueue : " + e.getMessage());
			}
			
		}
		
		for(int i = 0; i< 10; i++)
		{
			try
			{
				System.out.println("dequeue : " + rb.dequeue());
			}
			catch(Exception e)
			{
				System.out.println("dequeue : " + e.getMessage());
			}
			
		}
		
	}

	private int size;
	private int header; //for dequeue
	private int tail; //for enqueue
	private Item[] buffer;
	
	@SuppressWarnings("unchecked")
	public RingBuffer(Class<Item> clazz, int size)
	{
		this.size = size;
		buffer = (Item[])Array.newInstance(clazz, size);
	}
	
	public boolean isFull()
	{
		return tail == header && buffer[tail] != null;
	}
	
	public boolean isEmpty()
	{
		
		return header == tail && buffer[tail] == null;
	}
	
	public void enqueue(Item item)
	{
		if(isFull())
		{
			throw new RuntimeException("Full");
		}
		buffer[tail] = item;
		tail = (tail + 1) % size;
	}
	
	public Item dequeue() 
	{
		if(isEmpty())
		{
			throw new RuntimeException("Empty");
		}
		Item item = buffer[header];
		buffer[header] = null;
		header = (header + 1) % size;
		return item;
	}
}
